/* Includes ------------------------------------------------------------------*/
#include "MyApplication.h"

/* Private define-------------------------------------------------------------*/
#define HMI_REC_BUFFER_LENGTH 20        //接收缓存长度
#define PROTOCOL_DATA_LEN   7           //协议数据长度（HMI屏幕的按键值）
/* Private variables----------------------------------------------------------*/
static uint8_t ucHMI_Rec_Buffer[HMI_REC_BUFFER_LENGTH] = {0x00};    //接收缓存
static uint8_t ucHMI_Send_Motor_Crile_Buffer[9] = {'n','0','.','v','a','l','=','0','\0'};  //圈数发送缓存
static uint8_t ucHMI_Send_Motor_Speed_Buffer[9] = {'n','1','.','v','a','l','=','0','\0'};  //速度发送缓存
static uint8_t ucHMI_EndData[3] = {0xFF,0xFF,0xFF};                 //数据结束符

static void HMI_SendEndData(void);
static void HMI_SendString(uint8_t* );
static void HMI_Init(void);
static void HMI_Protocol(void);
/* Public variables-----------------------------------------------------------*/
HMI_t HMI = 
{
    Page_Main,
    ucHMI_Rec_Buffer,
    ucHMI_Send_Motor_Crile_Buffer,
    ucHMI_Send_Motor_Speed_Buffer,
    0,
    FALSE,            //标志位为FALSE，默认是按键触发
    0,

    HMI_SendString,
    HMI_Init,
    HMI_Protocol
};
/* Private function prototypes------------------------------------------------*/

/*
* @name   HMI_SendEndData
* @brief  往HMI屏发送结束符
* @param  None
* @retval None   
*/
static void HMI_SendEndData()
{
    //通过串口发送0xFF 0xFF 0xFF结束符
    HAL_UART_Transmit(&huart1,ucHMI_EndData,3,0x0A);
}

/*
* @name   HMI_SendString
* @brief  往HMI屏发送数据
* @param  pucStr：待发送的数据
* @retval None   
*/
static void HMI_SendString(uint8_t* pucStr)
{
    //通过串口往HMI屏幕发送数据
    HAL_UART_Transmit(&huart1,pucStr,strlen((const char*)pucStr),0x0A);
    //每一次发送数据，都要发送结束符
    HMI_SendEndData();
}

/*
* @name   HMI_Init
* @brief  HMI初始化
* @param  None
* @retval None   
*/
static void HMI_Init()
{
    HMI_SendEndData();                      //先发送结束符，避免杂乱数据
    HMI_SendString((uint8_t *)"page 0");   //HMI显示主页面main
}

/*
* @name   HMI_Protocol
* @brief  HMI协议
* @param  None
* @retval None   
*/
static void HMI_Protocol()
{
    uint8_t index = 0,i = 0;
    uint8_t Temp_Array[7] = {0x00};
    //串口1停止DMA接收
    HAL_UART_DMAStop(&huart1);

    //读取HMI缓存数据，共7个字节，起始值为0x65
    for(i=0;i<7;i++)
    {
        //检测键值起始数据0x65
        if(index == 0)
        {
            //从下标0开始找，如果不是0x65开头，则从该位往后的共7个字节的数据都不是正确数据，舍弃
            if(*(HMI.pucRec_Buffer+i) != 0x65){continue;}
        }
        //如果找到0x65，则往后的7个字节数据是HMI传来的数据，则进行数据保存
        Temp_Array[index] = *(HMI.pucRec_Buffer+i);
        //如果已经读到7个字节数据,就退出循环
        if(index == PROTOCOL_DATA_LEN)
        {
            break;
        }
        index++;
    }
    //串口1开启DMA接收
    HAL_UART_Receive_DMA(&huart1,HMI.pucRec_Buffer,(uint16_t)20);

    //处理数据
    if(index == PROTOCOL_DATA_LEN)
    {
        //主页面的键值信息
        if(Temp_Array[1] == 0x00)
        {
            //数码管按键弹起事件
            //下标为3的数据表示按钮按下或弹起，按下：0x01,弹起：0x00
            if(Temp_Array[2] == 0x01 && Temp_Array[3] == 0x00)
            {
                HMI.Page = Page_Display;        //切换到数码管显示页面
                Display.HMI_Or_SHT30_Control_Flag = Display_HMI;    //串口屏控制数码管
                Display.Disp_Clr();             //清除数码管
            }

            //步进电机按键弹起事件
            if(Temp_Array[2] == 0x03 && Temp_Array[3] == 0x00)
            {
                HMI.Page = Page_Step_Motor;     //切换到电机显示页面
                Display.HMI_Or_SHT30_Control_Flag = Display_HMI;    //串口屏控制数码管
                Display.Disp_Clr();             //清除数码管

                //数码管显示电机圈数和速度
                //显示圈数
                Display.Disp_Hex(Disp_NUM_6,Uniplar_Step_Motor.Circle,Disp_DP_OFF); 
                //显示速度
                Display.Disp_Hex(Disp_NUM_1,0,Disp_DP_OFF);
            }
        }

        //数码管页面的键值信息
        if(Temp_Array[1] == 0x01)
        {
            //返回键弹起事件
            if(Temp_Array[2] == 0x08 && Temp_Array[3] == 0x00)
            {
                HMI.Page = Page_Main;           //切换到主页面
                Display.HMI_Or_SHT30_Control_Flag = Display_SHT30;  //SHT30控制数码管
                Display.Disp_Clr();             //清除数码管
            }
        }
        
        //步进电机页面的键值信息
        if(Temp_Array[1] == 0x02)
        {
            //返回键弹起事件
            if(Temp_Array[2] == 0x02 && Temp_Array[3] == 0x00)
            {
                HMI.Page = Page_Main;           //切换到主页面
                Display.HMI_Or_SHT30_Control_Flag = Display_SHT30;  //SHT30控制数码管
                //关闭步进电机
                Uniplar_Step_Motor.Status = Stop_Status;    //电机状态切换为停止
                CLR_Motor_A;
                CLR_Motor_B;
                CLR_Motor_C;
                CLR_Motor_D;
                Uniplar_Step_Motor.Circle = 0;      //圈数清零
            }

            //开关按钮弹起事件
            if(Temp_Array[2] == 0x08 && Temp_Array[3] == 0x00)
            {
                //标志位置位
                HMI.Page_Step_Motor_KEY_Flag = TRUE;
                //调用外部中断回调函数，传入参数按键1，控制电机开启和停止
                HAL_GPIO_EXTI_Callback(KEY1_Pin);
                
                //按钮按下，文本变成关，电机启动，则发送电机圈数和速度
                if(Uniplar_Step_Motor.Status == Start_Status)
                {
                    HMI.pucSend_Motor_Cricle_Buffer[7] = Uniplar_Step_Motor.Circle+'0';
                    HMI.HMI_SendString(HMI.pucSend_Motor_Cricle_Buffer);     //屏幕显示圈数
                    //数码管显示速度
                    switch(Uniplar_Step_Motor.Speed)
					{
						case 100: Display.Disp_Hex(Disp_NUM_1,1,Disp_DP_OFF); HMI.ucSpeed_temp = 1;break;
						case 90:  Display.Disp_Hex(Disp_NUM_1,2,Disp_DP_OFF); HMI.ucSpeed_temp = 2;break;
						case 80:  Display.Disp_Hex(Disp_NUM_1,3,Disp_DP_OFF); HMI.ucSpeed_temp = 3;break;
						case 70:  Display.Disp_Hex(Disp_NUM_1,4,Disp_DP_OFF); HMI.ucSpeed_temp = 4;break;
						case 60:  Display.Disp_Hex(Disp_NUM_1,5,Disp_DP_OFF); HMI.ucSpeed_temp = 5;break;
						case 50:  Display.Disp_Hex(Disp_NUM_1,6,Disp_DP_OFF); HMI.ucSpeed_temp = 6;break;
						case 40:  Display.Disp_Hex(Disp_NUM_1,7,Disp_DP_OFF); HMI.ucSpeed_temp = 7;break;
						case 30:  Display.Disp_Hex(Disp_NUM_1,8,Disp_DP_OFF); HMI.ucSpeed_temp = 8;break;
						case 20:  Display.Disp_Hex(Disp_NUM_1,9,Disp_DP_OFF); HMI.ucSpeed_temp = 9;break;
						default: break;
					}
                    //往屏幕发送显示速度指令
                    HMI.pucSend_Motor_Speed_Buffer[7] = HMI.ucSpeed_temp+'0';
                    HMI.HMI_SendString(HMI.pucSend_Motor_Speed_Buffer);
                }
                //按钮再被按下，文本变成开，电机关闭，则发送指令清除电机圈数，清除标志位
                else
                {
                    HMI.HMI_SendString((uint8_t*)"n0.val=0");     //清零屏幕圈数
                    HMI.HMI_SendString((uint8_t*)"n1.val=0");     //清零屏幕速度
                    Display.Disp_Hex(Disp_NUM_1,0,Disp_DP_OFF);
                }
                
                //标志位清零
                HMI.Page_Step_Motor_KEY_Flag = FALSE;
            }
            //正反按钮弹起事件
            if(Temp_Array[2] == 0x09 && Temp_Array[3] == 0x00)
            {
                //标志位置位
                HMI.Page_Step_Motor_KEY_Flag = TRUE;
                //调用外部中断回调函数，传入参数按键2，控制电机正反转
                HAL_GPIO_EXTI_Callback(KEY2_Pin);
                //标志位清零
                HMI.Page_Step_Motor_KEY_Flag = FALSE;
            }
            //加速按钮弹起事件
            if(Temp_Array[2] == 0x0A && Temp_Array[3] == 0x00)
            {
                //标志位置位
                HMI.Page_Step_Motor_KEY_Flag = TRUE;
                //调用外部中断回调函数，传入参数按键3，控制电机加速
                HAL_GPIO_EXTI_Callback(KEY3_Pin);
                //标志位清零
                HMI.Page_Step_Motor_KEY_Flag = FALSE;
            }
            //减速按钮弹起事件
            if(Temp_Array[2] == 0x0B && Temp_Array[3] == 0x00)
            {
                //标志位置位
                HMI.Page_Step_Motor_KEY_Flag = TRUE;
                //调用外部中断回调函数，传入参数按键4，控制电机减速
                HAL_GPIO_EXTI_Callback(KEY4_Pin);
                //标志位清零
                HMI.Page_Step_Motor_KEY_Flag = FALSE;
            }
        }
    }
}
/********************************************************
  End Of File
********************************************************/
